from sqlalchemy.orm import Session
from typing import List, Optional
from datetime import datetime
import uuid
import json

from db.models import MtasksExecutionRecord
from schemas.execution_record import ExecutionRecordCreate, ExecutionRecordUpdate

class ExecutionRecordService:
    @staticmethod
    def _prepare_record_for_response(record):
        """将数据库记录中的 JSON 字符串转换为 Python 对象"""
        if record:
            # 转换 logs 字段
            if record.logs:
                try:
                    record.logs = json.loads(record.logs)
                except json.JSONDecodeError:
                    record.logs = []
            else:
                record.logs = []
                
            # 转换 outputFiles 字段
            if record.outputFiles:
                try:
                    record.outputFiles = json.loads(record.outputFiles)
                except json.JSONDecodeError:
                    record.outputFiles = []
            else:
                record.outputFiles = []
        return record

    @staticmethod
    def get_execution_record(db: Session, record_id: str) -> Optional[MtasksExecutionRecord]:
        record = db.query(MtasksExecutionRecord).filter(MtasksExecutionRecord.id == record_id).first()
        return ExecutionRecordService._prepare_record_for_response(record)

    @staticmethod
    def get_execution_records(
        db: Session, 
        skip: int = 0, 
        limit: int = 100,
        task_id: Optional[str] = None
    ) -> List[MtasksExecutionRecord]:
        query = db.query(MtasksExecutionRecord)
        if task_id:
            query = query.filter(MtasksExecutionRecord.taskId == task_id)
        records = query.offset(skip).limit(limit).all()
        return [ExecutionRecordService._prepare_record_for_response(record) for record in records]

    @staticmethod
    def create_execution_record(db: Session, record: ExecutionRecordCreate) -> MtasksExecutionRecord:
        record_data = record.model_dump()
        
        # 转换日志和输出文件为JSON字符串
        if 'logs' in record_data:
            logs = record_data['logs'] or []
            if logs and hasattr(logs[0], 'model_dump'):
                record_data['logs'] = json.dumps([log.model_dump() for log in logs])
            else:
                record_data['logs'] = json.dumps(logs)
                
        if 'outputFiles' in record_data:
            output_files = record_data['outputFiles'] or []
            if output_files and hasattr(output_files[0], 'model_dump'):
                record_data['outputFiles'] = json.dumps([file.model_dump() for file in output_files])
            else:
                record_data['outputFiles'] = json.dumps(output_files)

        db_record = MtasksExecutionRecord(
            **record_data,
            createdAt=datetime.utcnow().isoformat()
        )
        db_record.id = str(uuid.uuid4())
        db.add(db_record)
        db.commit()
        db.refresh(db_record)
        return ExecutionRecordService._prepare_record_for_response(db_record)

    @staticmethod
    def update_execution_record(
        db: Session, 
        record_id: str, 
        record: ExecutionRecordUpdate
    ) -> Optional[MtasksExecutionRecord]:
        db_record = ExecutionRecordService.get_execution_record(db, record_id)
        if not db_record:
            return None
        
        update_data = record.model_dump(exclude_unset=True)
        
        # 转换日志和输出文件为JSON字符串
        if 'logs' in update_data:
            logs = update_data['logs'] or []
            if logs and hasattr(logs[0], 'model_dump'):
                update_data['logs'] = json.dumps([log.model_dump() for log in logs])
            else:
                update_data['logs'] = json.dumps(logs)
                
        if 'outputFiles' in update_data:
            output_files = update_data['outputFiles'] or []
            if output_files and hasattr(output_files[0], 'model_dump'):
                update_data['outputFiles'] = json.dumps([file.model_dump() for file in output_files])
            else:
                update_data['outputFiles'] = json.dumps(output_files)

        for field, value in update_data.items():
            setattr(db_record, field, value)
        
        db.commit()
        db.refresh(db_record)
        # 在更新后重新获取记录，以便应用 JSON 解析
        return ExecutionRecordService._prepare_record_for_response(db_record)

    @staticmethod
    def delete_execution_record(db: Session, record_id: str) -> bool:
        db_record = ExecutionRecordService.get_execution_record(db, record_id)
        if not db_record:
            return False
        
        db.delete(db_record)
        db.commit()
        return True 